/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.elecciones.Validador;

import com.elecciones.Beans.Candidato;
import com.elecciones.Beans.Voto;
import com.elecciones.DAO.votosDAO;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author open12
 */
public class validadorGramatica {

  private String codigo;
  private String resultado = "";
  private String respuestaOk = "";
  private String error = "";
  private Candidato candidato = new Candidato();
  private Voto voto = new Voto();
  private ArrayList<Candidato> listaCandidatos = new ArrayList<>();
  private ArrayList<Voto> listaVotos = new ArrayList<>();
  private int contador = 0;

  public ArrayList<Candidato> getListaCandidatos() {
    return listaCandidatos;
  }

  public void setListaCandidatos(ArrayList<Candidato> listaCandidatos) {
    this.listaCandidatos = listaCandidatos;
  }

  public ArrayList<Voto> getListaVotos() {
    return listaVotos;
  }

  public void setListaVotos(ArrayList<Voto> listaVotos) {
    this.listaVotos = listaVotos;
  }

  public validadorGramatica(String codigo) {
    this.codigo = codigo;
  }

  public validadorGramatica() {
  }

  public String getCodigo() {
    return codigo;
  }

  public void setCodigo(String codigo) {
    this.codigo = codigo;
  }

  public String getResultado() {
    return resultado;
  }

  public String getRespuestaOk() {
    return respuestaOk;
  }

  public void setRespuestaOk(String respuestaOk) {
    this.respuestaOk = respuestaOk;
  }

  public String getError() {
    return error;
  }

  public void setError(String error) {
    this.error = error;
  }

  public int getContador() {
    return contador;
  }

  public void setContador(int contador) {
    this.contador = contador;
  }

  public void validar() {
    ArrayList<String> vBloques = new ArrayList(Arrays.asList(codigo.split("crear")));
    for (String vBloque : vBloques) {
      if (!vBloque.equals("")) {
        ArrayList<String> vConceptos = new ArrayList(Arrays.asList(vBloque.split("\r\n")));
        int nTipoConcepto = 100;
        for (int j = 0; j < vConceptos.size(); j++) {
          setContador(contador + 1);
          String entidad = vConceptos.get(j).trim();
          int nPregunta = entidad.indexOf("?");
          if (j == 0) {
            nTipoConcepto = numeroConcepto(entidad);
          } else {
            if (nPregunta == -1) {
              switch (nTipoConcepto) {
                case 0:
                  resultado += "Error el concepto: " + entidad + " no existe. Linea: " + getContador() + "<br>";
                  break;
                case 1:
                  validacionAtributosPorConcepto(1, entidad);
                  validarParaInsertar("candidato");
                  break;
                case 2:
                  validacionAtributosPorConcepto(2, entidad);
                  validarParaInsertar("voto");
                  break;
              }
            } else {
              //caso para las preguntas
              validarPregunta(entidad);
              if (this.respuestaOk != null && !this.respuestaOk.isEmpty()) {
                resultado += getRespuestaOk();
              } else if (this.error != null && !this.error.isEmpty()) {
                resultado += getError();
              }
            }
          }
        }
      }
    }
  }

  public int numeroConcepto(String concepto) {
    int nConcepto = 0;
    switch (concepto) {
      case "candidato":
        nConcepto = 1;
        break;
      case "voto":
        nConcepto = 2;
        break;
    }
    return nConcepto;
  }

  public void validacionAtributosPorConcepto(int nEntidad, String entidad) {
    ArrayList<String> vAtributos = new ArrayList(Arrays.asList(entidad.split("=")));
    switch (nEntidad) {
      case 1:
        switch (vAtributos.get(0).trim()) {
          case "#tarjeton":
            try {
              candidato.setTarjeton(Integer.parseInt(vAtributos.get(1).trim()));
            } catch (NumberFormatException e) {
              this.resultado += "Debe escribir un numero para el tarjeton. Linea: " + getContador() + "<br>";
            }
            break;
          case "nombre":
            candidato.setNombre(vAtributos.get(1).trim());
            break;
          case "apellido":
            candidato.setApellido(vAtributos.get(1).trim());
            break;
          case "#identificacion":
            candidato.setIdentificacion(vAtributos.get(1).trim());
            break;
          case "partido":
            candidato.setPartidoPolitico(vAtributos.get(1).trim());
            break;
          case "genero":
            if ((!vAtributos.get(1).trim().equals("m") && !vAtributos.get(1).equals("f"))) {
              this.resultado += "Error el genero: debe ser M o F para el Candidato. Linea: " + getContador() + " <br>";
            } else {
              candidato.setGenero(vAtributos.get(1).trim());
            }
            break;
          default:
            this.resultado += "Error el Atributo: " + vAtributos.get(0) + " no existe para el Candidato. Linea: " + getContador() + " <br>";
            break;
        }
        break;
      case 2:
        switch (vAtributos.get(0).trim()) {
          case "genero":
            if ((!vAtributos.get(1).trim().equals("m") && !vAtributos.get(1).equals("f"))) {
              this.resultado += "Error el genero: debe ser M o F para el Voto. Linea: " + getContador() + " <br>";
            } else {
              voto.setGenero(vAtributos.get(1).trim());
            }
            break;
          case "#tarjeton":
            try {
              voto.setNumeroTarjeton(Integer.parseInt(vAtributos.get(1).trim()));
            } catch (NumberFormatException e) {
              this.resultado += "Debe Escribir el Numero del Tarjeton en el Voto. Linea: " + getContador() + " <br>";
            }
            break;
          case "ciudad":
            voto.setCiudad(vAtributos.get(1).trim());
            break;
          case "#cedula":
            try {
              voto.setCedula(vAtributos.get(1).trim());
            } catch (NumberFormatException e) {
              this.resultado += "Debe Escribir la Cedula para el Voto. Linea: " + getContador() + " <br>";
            }

            break;
          default:
            this.resultado += "Error el Atributo: " + vAtributos.get(0) + " no existe para el Voto. Linea: " + getContador() + " <br>";
        }
        break;
    }
  }

  public void validarParaInsertar(String concepto) {
    boolean bandera = true;
    switch (concepto) {
      case "candidato":
        if (candidato.getTarjeton() == 0) {
          bandera = false;
        }
        if (candidato.getNombre() == null) {
          bandera = false;
        }
        if (candidato.getApellido() == null) {
          bandera = false;
        }
        if (candidato.getIdentificacion() == null) {
          bandera = false;
        }
        if (candidato.getPartidoPolitico() == null) {
          bandera = false;
        }
        if (candidato.getGenero() == null) {
          bandera = false;
        }
        if (bandera) {
          listaCandidatos.add(candidato);
          limpiar("candidato");
        }
        break;
      case "voto":
        if (voto.getCedula() == null) {
          bandera = false;
        }
        if (voto.getGenero() == null) {
          bandera = false;
        }
        if (voto.getCiudad() == null) {
          bandera = false;
        }
        if (voto.getNumeroTarjeton() == 0) {
          bandera = false;
        }
        if (bandera) {
          listaVotos.add(voto);
          limpiar("voto");
        }
        break;
    }
  }

  public void limpiar(String concepto) {
    switch (concepto) {
      case "candidato":
        this.candidato = new Candidato();
        break;
      case "voto":
        this.voto = new Voto();
        break;
    }
  }

  public void validarPregunta(String pregunta) {
    boolean param1 = false;
    boolean param2 = false;
    boolean param3 = false;
    String errorSintaxis = "";
    String[] cadenaValida = pregunta.split(" ");
    if (cadenaValida.length == 5) {
      switch (cadenaValida[0]) {
        case "?":
          param1 = true;
          break;
      }
      switch (cadenaValida[1]) {
        case "votos":
          param2 = true;
          break;
      }
      switch (cadenaValida[2]) {
        case "por":
          param3 = true;
          break;
      }
      if (param1 && param2 && param3) {
        switch ((cadenaValida[3])) {
          case "candidato":
            if (esEntero(cadenaValida[4])) {
              try {
                votosDAO voto = new votosDAO();
                String parametro = pregunta;
                String prsXCand = voto.personasXCandidato(parametro);
                setRespuestaOk("El Candidato Tiene: " + prsXCand + " votos <br>");
              } catch (SQLException ex) {
                Logger.getLogger(validadorGramatica.class.getName()).log(Level.SEVERE, null, ex);
              }
            } else {
              setRespuestaOk("El quinto parametro debe ser un entero. Linea: " + getContador() + " <br>");
            }
            break;
          case "ciudad":
            if (("max".equals(cadenaValida[4]))) {
              try {
                votosDAO voto = new votosDAO();
                String parametro = pregunta;
                String prsXCand[] = voto.ciudadXCandidato(parametro);
                String ciudadConsul = "ciudad con mayor votos: " + prsXCand[1] + " con " + prsXCand[0] + " votos <br>";
                setRespuestaOk(ciudadConsul);
              } catch (SQLException ex) {
                Logger.getLogger(validadorGramatica.class.getName()).log(Level.SEVERE, null, ex);
              }
            } else {
              setRespuestaOk("Error sintaxis en quito parametro. Linea: " + getContador() + " <br>");
            }
            break;
          case "ganador":
            if (("candidato".equals(cadenaValida[4]))) {
              try {
                votosDAO voto = new votosDAO();
                String candGanador[] = voto.candidatoGanador();
                setRespuestaOk("El candidato ganador es " + candGanador[1] + " con: " + candGanador[0] + " votos <br>");
              } catch (SQLException ex) {
                Logger.getLogger(validadorGramatica.class.getName()).log(Level.SEVERE, null, ex);
              }
            } else {
              setRespuestaOk("Error sintaxis en quito parametro. Linea: " + getContador() + " <br>");
            }
            break;
          case "partido":
            if (("max".equals(cadenaValida[4]))) {
              try {
                votosDAO voto = new votosDAO();
                String candGanador[] = voto.partidoGanador();
                setRespuestaOk("El partido con mas votos es " + candGanador[1] + " con: " + candGanador[0] + " votos <br>");
              } catch (SQLException ex) {
                Logger.getLogger(validadorGramatica.class.getName()).log(Level.SEVERE, null, ex);
              }
            } else {
              setRespuestaOk("Error sintaxis en quito parametro. Linea: " + getContador() + " <br>");
            }
            break;
          case "genero":
            if (("m".equals(cadenaValida[4]))) {
              try {
                votosDAO voto = new votosDAO();
                int genero = voto.Genero(cadenaValida[4]);
                setRespuestaOk("Hubieron " + genero + " votos del genero Masculino <br>");
              } catch (SQLException ex) {
                Logger.getLogger(validadorGramatica.class.getName()).log(Level.SEVERE, null, ex);
              }
            } else if (("f".equals(cadenaValida[4]))) {
              try {
                votosDAO voto = new votosDAO();
                int genero = voto.Genero(cadenaValida[4]);
                setRespuestaOk("Hubieron " + genero + " votos del genero Femenino <br>");
              } catch (SQLException ex) {
                Logger.getLogger(validadorGramatica.class.getName()).log(Level.SEVERE, null, ex);
              }
            } else {
              setRespuestaOk("Error sintaxis en quito parametro. Linea: " + getContador() + " <br>");
            }
            break;
          default:
            setRespuestaOk("Error sintaxis en cuarto parametro. Linea: " + getContador() + " <br>");
            break;

        }
      } else {
        if (!param1) {
          errorSintaxis += "Error sintaxis en primer parametro. Linea: " + getContador() + " <br>";
        }
        if (!param2) {
          errorSintaxis += "Error sintaxis en segundo parametro. Linea: " + getContador() + " <br>";
        }
        if ((!param3)) {
          errorSintaxis += "Error sintaxis en terecer parametro. Linea: " + getContador() + " <br>";
        }
        setRespuestaOk(errorSintaxis);
      }
    } else {
      String validadndo = "";
      if (cadenaValida.length < 5) {
        validadndo = "Verefique<br> Faltan Parametros. Linea: " + getContador() + " <br>";
      } else if (cadenaValida.length > 5) {
        validadndo = "Verefique<br> Sobran Parametros. Linea: " + getContador() + " <br>";
      }
      setRespuestaOk(validadndo);
    }
  }

  public static boolean esEntero(String input) {
    boolean parsable = true;
    try {
      Integer.parseInt(input);
    } catch (NumberFormatException e) {
      parsable = false;
    }
    return parsable;
  }
}
